﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;

namespace Jacaranda.Model
{
    public abstract class ComparableNode : ConditionalExpression
    {
        public ComparableNode ToLower()
        {
            return new ToLowerFunction() { Operand = this };
        }

        public ComparableNode StartsWith(string pattern)
        {
            return new StartsWithFunction() { Operand1 = this, Operand2 = pattern };
        }

        public ComparableNode StartsWith(ComparableNode node)
        {
            return new StartsWithFunction() { Operand1 = this, Operand2 = node };
        }

        public ComparableNode Length()
        {
            return new LengthFunction() { Operand = this };
        }

        public ComparableNode Left(ComparableNode operand)
        {
            return new LeftFunction() { Operand1 = this, Operand2 = operand };
        }

        public ComparableNode Left(int length)
        {
            return new LeftFunction() { Operand1 = this, Operand2 = length };
        }

        public ComparableNode Right(ComparableNode operand)
        {
            return new RightFunction() { Operand1 = this, Operand2 = operand };
        }

        public ComparableNode Right(int length)
        {
            return new RightFunction() { Operand1 = this, Operand2 = length };
        }

        public ComparableNode IsDistinct()
        {
            return new IsDistinctFunction() { Operand = this };
        }


        //public ConditionalExpression In<T>(AbstractProperty property, ConditionalExpression condition) where T : Entity
        //{
        //    return new FieldMatchCriteria() { Field = this, Value = new SelectMatchCriteria(typeof(T).Name, property.Name, condition) };
        //}


        public static FieldMatchCriteria operator +(ComparableNode operand1, object operand2)
        {
            return new FieldMatchCriteria() { Field = operand1, Operator = BinaryOperator.Addition, Value = operand2 };
        }

        public static FieldMatchCriteria operator -(ComparableNode operand1, object operand2)
        {
            return new FieldMatchCriteria() { Field = operand1, Operator = BinaryOperator.Substraction, Value = operand2 };
        }

        public static FieldMatchCriteria operator *(ComparableNode operand1, object operand2)
        {
            return new FieldMatchCriteria() { Field = operand1, Operator = BinaryOperator.Multiplication, Value = operand2 };
        }

        public static FieldMatchCriteria operator /(ComparableNode operand1, object operand2)
        {
            return new FieldMatchCriteria() { Field = operand1, Operator = BinaryOperator.Division, Value = operand2 };
        }

        public static FieldMatchCriteria operator ==(ComparableNode operand1, object operand2)
        {
            return new FieldMatchCriteria() { Field = operand1, Operator = BinaryOperator.Equals, Value = operand2 };
        }

        public static FieldMatchCriteria operator !=(ComparableNode operand1, object operand2)
        {
            return new FieldMatchCriteria() { Field = operand1, Operator = BinaryOperator.DoesNotEqual, Value = operand2 };
        }

        public static FieldMatchCriteria operator %(ComparableNode operand1, object operand2)
        {
            return new FieldMatchCriteria() { Field = operand1, Operator = BinaryOperator.Contains, Value = operand2 };
        }

        public static FieldMatchCriteria operator >(ComparableNode operand1, object operand2)
        {
            return new FieldMatchCriteria() { Field = operand1, Operator = BinaryOperator.GreaterThan, Value = operand2 };
        }

        public static FieldMatchCriteria operator >=(ComparableNode operand1, object operand2)
        {
            return new FieldMatchCriteria() { Field = operand1, Operator = BinaryOperator.GreaterOrEqualThan, Value = operand2 };
        }

        public static FieldMatchCriteria operator <(ComparableNode operand1, object operand2)
        {
            return new FieldMatchCriteria() { Field = operand1, Operator = BinaryOperator.LessThan, Value = operand2 };
        }

        public static FieldMatchCriteria operator <=(ComparableNode operand1, object operand2)
        {
            return new FieldMatchCriteria() { Field = operand1, Operator = BinaryOperator.LessOrEqualThan, Value = operand2 };
        }


        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }
    }
}
